home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
dviware
/
dvitovdu32
/
src
/
pascal
/
vis240vdu.p
< prev
next >
Wrap
Text File
|
1991-11-10
|
10KB
|
311 lines
(* VDU routines for a VIS240 terminal. *)
#include 'globals.h';
#include 'screenio.h';
#include 'vdu.h';
VAR
charht : INTEGER; (* set in LoadFont and used in ShowChar *)
lastv : INTEGER; (* ShowChar remembers last vertical coordinate *)
(******************************************************************************)
PROCEDURE StartText;
(* We are about to draw text in dialogue region. *)
BEGIN
WriteChar(ESC);
WriteChar(CHR(134b)); (* leave graphics mode *)
END; (* StartText *)
(******************************************************************************)
PROCEDURE MoveAbs (row, col : INTEGER);
(* Move cursor to given screen position. *)
BEGIN
WriteChar(ESC); WriteChar('[');
WriteInt(row);
WriteChar(';');
WriteInt(col);
WriteChar('H');
END; (* MoveAbs *)
(******************************************************************************)
PROCEDURE MoveToTextLine (line : INTEGER);
(* Move current position to start of given line. *)
BEGIN
MoveAbs(line,1);
END; (* MoveToTextLine *)
(******************************************************************************)
PROCEDURE ClearTextLine (line : INTEGER);
(* Erase given line; note that DVItoVDU does not assume anything about the
current position at the end of this routine.
*)
BEGIN
MoveAbs(line,1);
WriteChar(ESC);
WriteString('[K'); (* erase to end of line *)
END; (* ClearTextLine *)
(******************************************************************************)
PROCEDURE StartGraphics;
(* We are about to draw in window region. *)
BEGIN
WriteChar(ESC);
WriteString('Pp'); (* enter graphics mode *)
lastv := 999999; (* undefined value for next ShowChar call *)
END; (* StartGraphics *)
(******************************************************************************)
PROCEDURE ClearScreen;
BEGIN
WriteChar(ESC);
WriteString('[2J'); (* erase entire screen *)
(* note that VT125 has a separate graphics plane which we need to erase *)
StartGraphics; (* switch to REGIS mode *)
WriteString('S(E)'); (* erase graphics plane *)
StartText; (* exit in text mode *)
END; (* ClearScreen *)
(******************************************************************************)
PROCEDURE LoadFont (fontname : string;
fontsize : INTEGER;
mag, hscale, vscale : REAL);
(* Use the given information to select an appropriate character size
(based on horizontal AND vertical scaling) for future calls of ShowChar.
*)
VAR wd, ht : INTEGER; (* we will send T ( Swd Hht ) *)
BEGIN
WriteChar('T');
WriteChar('(');
(* scale fontsize horizontally and choose an appropriate text width *)
wd := TRUNC( (fontsize * mag * hscale) + 0.5 ) DIV 9;
IF wd > 16 THEN wd := 16; (* wd now in 0,1,2,...,16 *)
(* larger widths tend to be too big so adjust accordingly (trial and error) *)
IF wd > 1 THEN wd := wd DIV 2;
WriteChar('S');
WriteInt(wd);
(* scale fontsize vertically and choose an appropriate text height *)
ht := TRUNC( (fontsize * mag * vscale) + 0.5 ) DIV 10;
IF ht < 1 THEN ht := 1 (* ht must not be 0 *)
ELSE IF ht > 16 THEN ht := 16; (* ht now in 1,2,...,16 *)
charht := ht * 10; (* charht now in 10,20,30,...,160 *)
(* restrict charht to <= windowv so screenv-charht in ShowChar will be >= 0 *)
IF charht > windowv THEN BEGIN
charht := windowv;
ht := windowv DIV 10;
END;
(* now reduce charht by one fifth to allow for descenders in ShowChar *)
charht := ((charht * 4) DIV 5) - 1; (* exact if charht is multiple of 10 *)
WriteChar('H');
WriteInt(ht);
(* Note that VT125 and GIGI VDUs sometimes vary the vertical thickness of text
(only for odd ht values???). VT240 does not; instead, charht is sometimes
1 pixel too much and baseline won't agree with Box/Full characters!
*)
WriteChar(')');
END; (* LoadFont *)
(******************************************************************************)
PROCEDURE ShowChar (screenh, screenv : INTEGER;
ch : CHAR);
(* Show the given Terse character (mapped to ASCII) using the given position.
We remember the vertical position in lastv so we can reduce the output
bytes needed to position the next Terse character on the same line.
StartGraphics resets lastv to an undefined state (= 999999).
*)
VAR newch : CHAR; (* = TeXtoASCII[ch] *)
BEGIN
WriteChar('P'); WriteChar('[');
WriteInt(screenh);
(* charht allows for descenders and is used to shift ref pt of REGIS ch
(top left pixel) so that REGIS and TeX baselines will match.
LoadFont guarantees that screenv - charht >= 0.
*)
screenv := screenv - charht;
IF lastv <> screenv THEN BEGIN (* we need to send new vertical coordinate *)
WriteChar(',');
WriteInt(screenv);
lastv := screenv; (* remember for next ShowChar call *)
END;
WriteChar(']');
WriteChar('T');
newch := TeXtoASCII[ch]; (* convert TeX ch to ASCII *)
IF newch <> '''' THEN BEGIN
WriteChar(''''); (* open quoted string *)
IF newch <> '?' THEN
(* newch is similar to TeX ch *)
WriteChar(newch)
ELSE
(* attempt to display something other than ? *)
CASE ORD(ch) OF
13b..17b : (* ff, fi, fl, ffi, ffl *)
BEGIN
WriteChar('f');
(* REGIS doesn't care if no room at right edge *)
CASE ORD(ch) OF
13b : WriteChar('f') ;
14b : WriteChar('i') ;
15b : WriteChar('l') ;
16b,
17b : BEGIN
WriteChar('f');
IF ch = CHR(16b) THEN
WriteChar('i')
ELSE
WriteChar('l');
END;
END;
END;
31b : WriteChar('B'); (* German sharp S *)
32b, 33b, 35b, 36b : (* diphthongs: ae, oe, AE, OE *)
BEGIN
CASE ORD(ch) OF
32b : WriteChar('a') ;
33b : WriteChar('o') ;
35b : WriteChar('A') ;
36b : WriteChar('O')
END;
CASE ORD(ch) OF
32b, 33b : WriteChar('e') ;
35b, 36b : WriteChar('E')
END;
END;
40b : WriteChar('/'); (* Polish suppressed l and L *)
OTHERWISE
WriteChar('?');
END;
WriteChar(''''); (* close quoted string *)
END
ELSE BEGIN
WriteChar('"'); WriteChar(''''); WriteChar('"'); (* send "'" *)
END;
END; (* ShowChar *)
(******************************************************************************)
PROCEDURE ShowRectangle (screenh, screenv, (* top left pixel *)
width, height : INTEGER; (* size of rectangle *)
ch : CHAR); (* black pixel *)
(* Display the given rectangle (without using the given black pixel character).
DVItoVDU ensures the top left position is visible and the given
dimensions do not go beyond the window edges.
*)
BEGIN
IF height = 1 THEN BEGIN (* show row vector *)
WriteChar('P'); WriteChar('['); (* move cursor to start of row *)
WriteInt(screenh); WriteChar(',');
WriteInt(screenv);
(* call @R macrograph to draw starting pixel and begin row *)
WriteChar('@'); WriteChar('R');
WriteInt(width-1); WriteChar(']');
END
ELSE IF width = 1 THEN BEGIN (* show column vector *)
WriteChar('P'); WriteChar('['); (* move cursor to start of column *)
WriteInt(screenh); WriteChar(',');
WriteInt(screenv);
(* call @C macrograph to draw starting pixel and begin column *)
WriteChar('@'); WriteChar('C');
WriteInt(height-1); WriteChar(']');
END
ELSE BEGIN
(* assume height and width > 1 and use shading to fill rectangle *)
WriteChar('P'); WriteChar('['); WriteChar(','); (* position to last row *)
WriteInt(screenv+height-1);
(* call @E macrograph to define shading reference line and start
position command that moves to start of first row *)
WriteChar('@'); WriteChar('E');
WriteInt(screenh); WriteChar(',');
WriteInt(screenv);
(* call @R macrograph to draw starting pixel and begin rectangle *)
WriteChar('@'); WriteChar('R');
WriteInt(width-1);
(* call @D macrograph to disable shading *)
WriteChar('@'); WriteChar('D');
END;
END; (* ShowRectangle *)
(******************************************************************************)
PROCEDURE ResetVDU;
(* We don't do a hardware reset, but leave VDU gracefully. *)
BEGIN
StartGraphics; (* for following REGIS commands *)
WriteString('@.'); (* clear macrograph storage *)
WriteString('T(E)'); (* restore Text attributes saved in InitVDU *)
StartText; (* safer to leave in text mode *)
END; (* ResetVDU *)
(******************************************************************************)
PROCEDURE InitVDU;
(* The dialogue region is the top 4 lines.
The window region is the remaining area of the screen.
*)
BEGIN
DVIstatusl := 1;
windowstatusl := 2;
messagel := 3;
commandl := 4;
bottoml := 24;
(* DVItoVDU's coordinate scheme is the same as the REGIS scheme. *)
windowh := 0;
windowv := 80; (* = height of 4 dialogue lines (better for LoadFont if
windowv is a multiple of 10) *)
windowwd := 768;
windowht := 480 - windowv;
(* the VIS240/241 has more text lines and a bigger window region: *)
bottoml := 29;
windowwd := 800;
windowht := 580 - windowv;
StartGraphics; (* for following REGIS commands *)
(* Set Text and Writing attributes to known initial states. *)
(* save current Text attributes; will be restored by ResetVDU *)
WriteString('T(B)');
(* default character set, no italic slant, direction right, default text size *)
WriteString('T(A0,I0,D0,S1)');
(* solid fill, no alternate, normal, shading disabled, overlay *)
WriteString('W(P1,A0,N0,S0,V)');
(* Define some macrographs for frequently used strings in ShowRectangle. *)
WriteString('@.'); (* clear macrograph storage *)
WriteString('@:E]W(S1)P[@;'); (* @E = enable shading for filled rectangle *)
WriteString('@:D]W(S0)@;'); (* @D = disable shading *)
WriteString('@:R]V[]V[+@;'); (* @R = mid part of drawing a row vector *)
WriteString('@:C]V[]V[,+@;'); (* @C = mid part of drawing a column vector *)
StartText; (* safer to leave in text mode *)
END; (* InitVDU *)